' Amendment--Humans Amendment Validation Script
' 7/9/08 11:17 am

Option Strict Off
imports System
imports Humans=PHSRAG.Insight21.Humans
imports PHSRAG.Insight21.BusinessObjects
imports FormsManagement = PHSRAG.Insight21.FormsManagement
imports System.Collections
imports System.Web.UI
imports Utility=PHSRAG.Utility

module Script
	sub Main()
    
		' Pages for rediction
		const StaffPageRedirection = 0
		const AttachmentsPageRedirection = -1
		const overviewPageRedirection = -2
       
		dim attachmentsLogItemAdded as boolean = false
		dim selectedSites as new ArrayList()
		dim allowedSitesForPI = "|PHS|Partners|BWH|Faulkner|MGH|SRH|McLean|IHP|"
		dim staffSiteValidationMatrix as new Hashtable() 'Name of the site as the key, and a triplet as the value. 
		'The First object in the triplet is the display name of the site
		'The Second object in the triplet is the list of institutions the PI can be from to act as an investigator for the site
		'The Third object is the list of institutions the SRI can be from to act as an investigator for the site
		staffSiteValidationMatrix("SiteBWH") = new Triplet("BWH", "|PHS|Partners|BWH|", "|PHS|Partners|BWH|")
		staffSiteValidationMatrix("SiteFaulkner") = new Triplet("Faulkner", "|PHS|Partners|BWH|Faulkner|", "|PHS|Partners|BWH|Faulkner|")
		staffSiteValidationMatrix("SiteMGH") = new Triplet("MGH", "|PHS|Partners|MGH|", "|PHS|Partners|MGH|")
		staffSiteValidationMatrix("SiteNSMC") = new Triplet("NSMC", "|PHS|Partners|", "|PHS|Partners|NSMC|")
		staffSiteValidationMatrix("SiteNWH") = new Triplet("NWH", "|PHS|Partners|", "|PHS|Partners|NWH|")
		staffSiteValidationMatrix("SitePCHI") = new Triplet("PCHI", "|PHS|Partners|", "|PHS|Partners|PCHI|")
		staffSiteValidationMatrix("SiteSRH") = new Triplet("SRH", "|PHS|Partners|MGH|SRH|", "|PHS|Partners|MGH|SRH|")
		staffSiteValidationMatrix("SiteMcLean") = new Triplet("McLean", "|PHS|Partners|MGH|McLean|", "|PHS|Partners|MGH|McLean|")
		staffSiteValidationMatrix("SiteIHP") = new Triplet("IHP", "|PHS|Partners|MGH|IHP|", "|PHS|Partners|MGH|IHP|")
		
		

		' stores the documents needed
       	Dim documentsToBeAttached As new ArrayList() 
       	Dim questionnaireAnswers As ArrayList = intrinsicProtocolVersion.QuestionnaireAnswers
       	Dim qV As FormsManagement.QuestionnaireVersion
       	Dim questionnaireAnswer As FormsManagement.QuestionnaireAnswer

		' count the number of times they answered the Primary question on the sponorFunding questionnaire.
       	Dim primarySponsorCount as integer = 0
		Dim sponsorType as string
		Dim sponsorChange as boolean = false
		dim sponsorTypeNone as boolean = false
		dim verifyStaff as boolean = false
    
        For Each questionnaireAnswer In questionnaireAnswers
			'Validate staff only if the AME involves any staff changes
			if questionnaireAnswer.QuestionnaireVersion.Questionnaire.Name = "Amendment" then
				dim answers as System.Collections.ArrayList = questionnaireAnswer.GetAnswers("AmendStaff")
				if ( answers.Count > 0 ) then
					Dim primaryAnswer as FormsManagement.Answer = answers(0)
					if primaryAnswer.Value = "Y" then
						verifyStaff = true
					end if
				end if
			end if
			
			if questionnaireAnswer.QuestionnaireVersion.Questionnaire.Name = "Sponsor Funding" then
				sponsorChange = true
				if questionnaireAnswer.Action <> FormsManagement.QuestionnaireAnswer.UserAction.Remove then
					'If the sponsor type is None, then no primary sponsor is required
					Dim sponsorTypes as System.Collections.ArrayList = questionnaireAnswer.GetAnswers("SponsorType")
					if ( sponsorTypes.Count > 0 ) then
						if sponsorTypes(0).Value = "None" then
							sponsorTypeNone = true
						end if
					end if
					
					Dim answers as System.Collections.ArrayList = questionnaireAnswer.GetAnswers("PrimarySponsor")
						
					if ( answers.Count > 0 ) then
						Dim primaryAnswer as FormsManagement.Answer = answers(0)
						if primaryAnswer.Value = "Y" then
							primarySponsorCount = primarySponsorCount + 1
						end if
					end if
				end if
			end if ' end if questionnaireAnswer.QuestionnaireVersion.Questionnaire.Name = "Sponsor Funding" then

			' Create a validation error if there is a QA with a default name (for multiples) 
			' --> We do this so that "Move to Rex" doesn't fail when trying to move over blank forms
			' --> Note that we don't handle Sponsors b/c we only move over the primary sponsor to REX so blank
			' forms are okay and won't fail the "Move to Rex"
			if (questionnaireAnswer.Name = FormsManagement.Constants.QuestionnaireAnswerDefaultNames.Drugs)
				Dim category as string = "Drugs / Biologics / Dietary Supplements"
				Dim description as string = "You have indicated that the study will include a drug, biologic, or dietary supplement.  Please either complete the form or remove it from the study."
				Dim logItem As New Humans.LogItem(intrinsicCachePolicy, intrinsicProtocolProcess.Id, overviewPageRedirection, overviewPageRedirection, category, category, "", "", description, false)
				SaveLogItem(logItem)	
			else if (questionnaireAnswer.Name = FormsManagement.Constants.QuestionnaireAnswerDefaultNames.MedicalDevices)
				Dim category as string = "Medical Devices"
				Dim description as string = "You have indicated that the study will include a medical device.  Please either complete the form or remove it from the study."
				Dim logItem As New Humans.LogItem(intrinsicCachePolicy, intrinsicProtocolProcess.Id, overviewPageRedirection, overviewPageRedirection, category, category, "", "", description, false)
				SaveLogItem(logItem)	
			else if (questionnaireAnswer.Name = FormsManagement.Constants.QuestionnaireAnswerDefaultNames.Children)
				Dim category as string = "Children"
				Dim description as string = "You have indicated that the study will include a child population.  Please either complete the form or remove it from the study."
				Dim logItem As New Humans.LogItem(intrinsicCachePolicy, intrinsicProtocolProcess.Id, overviewPageRedirection, overviewPageRedirection, category, category, "", "", description, false)
				SaveLogItem(logItem)	
			end if
			
			if questionnaireAnswer.QuestionnaireVersion.Questionnaire.Name = "Performance Sites" then
				for each site as string in staffSiteValidationMatrix.Keys
					if (questionnaireAnswer.GetAnswers(site).Count > 0) then
						selectedSites.Add(site)
					end if
				next
			end if  'end if questionnaireAnswer.QuestionnaireVersion.Questionnaire.Name = "Performance Sites" then
		next 'QUESTIONNAIRE ANSWER
		
		if (verifyStaff) then
			'StudyStaff Validation
			Dim studyStaffCollection as new Humans.StudyStaff(intrinsicCachePolicy)
			studyStaffCollection.Load(intrinsicConnection, intrinsicProtocolProcess.protocolId, intrinsicProtocolProcess.Id)
			Dim studyStaff as new ArrayList()
			studyStaff = studyStaffCollection.GetStudyStaffList()
			
			'Validate PI count and each staff role
			dim piCount as integer = 0
			dim pi as Humans.StaffPerson
			for each staffPerson as Humans.StaffPerson in studyStaff
				if (staffPerson.Role = "Principal Investigator") then
					pi = staffPerson
					piCount = piCount + 1
				end if
				if (staffPerson.Role = "") then
					LogMissingItem(StaffPageRedirection, StaffPageRedirection, "Study Staff", "Study Staff", "Staff Role", "", _
										string.format("{0}, {1} must be assigned with a role.", staffPerson.LastName, staffPerson.FirstName))
				end if
			next
			if (piCount > 1) then
				LogMissingItem(StaffPageRedirection, StaffPageRedirection, "Study Staff", "Study Staff", "PI Organization", "", _
								"Protocol can only have one staffed Principal Investigator.")
			else if (piCount = 0 or intrinsicProtocol.PIPersonId = 0) then
				LogMissingItem(StaffPageRedirection, StaffPageRedirection, "Study Staff", "Study Staff", "PI Organization", "", _
								"Protocol must have a staffed Principal Investigator.")
			end if
			
			'Validate PI Organization
			if (piCount = 1) then 
				dim isPISiteValid as boolean = false
				dim institutionOrganizationName as string = pi.InstitutionalName
				if (string.IsNullOrEmpty(institutionOrganizationName)) then
					institutionOrganizationName = pi.OrganizationName
				end if
				if (allowedSitesForPI.IndexOf(string.format("|{0}|", institutionOrganizationName)) <= 0) then
					LogMissingItem(StaffPageRedirection, StaffPageRedirection, "Study Staff", "Study Staff", "PI Organization", "", _ 
								"Principal Investigator must belong to one of PHS/Partners/BWH/Faulkner/MGH/SRH/McLean.")
				end if
			end if
			
			'Validate the rest of the staff vs sites selected
			dim validSites as string
			for each site as string in selectedSites
				dim validStaffForSiteFound as boolean = false
				for each staffPerson as Humans.StaffPerson in studyStaff
					dim institutionOrganizationName as string = staffPerson.InstitutionalName
					if (string.IsNullOrEmpty(institutionOrganizationName)) then
						institutionOrganizationName = staffPerson.OrganizationName
					end if
					if (staffPerson.Role = "Principal Investigator") then
						validSites = ctype(staffSiteValidationMatrix(site), Triplet).Second.ToString()
						if (validSites.IndexOf(institutionOrganizationName) > 0) then
							validStaffForSiteFound = true
							exit for
						end if
					end if
					if (staffPerson.Role = "Site Responsible Investigator") then
						validSites = ctype(staffSiteValidationMatrix(site), Triplet).Third.ToString()
						if (validSites.IndexOf(institutionOrganizationName) > 0) then
							validStaffForSiteFound = true
							exit for
						end if
					end if
				next
				if (not validStaffForSiteFound) then
							LogMissingItem(StaffPageRedirection, StaffPageRedirection, "Study Staff", "Study Staff", "Staff role", "", _
								string.Format("Site '{0}' does not have a valid Investigator.", ctype(staffSiteValidationMatrix(site), Triplet).First.ToString()))
				end if
			next
		end if  'verifyStaff 
		
		
		dim verifiedQuestionnaires as string = "|"
		For Each questionnaireAnswer In questionnaireAnswers
			qv = questionnaireAnswer.QuestionnaireVersion
			'Check if this type of document was already verified with the attachments
			dim verifyQuestionnaire = "|" + qv.Questionnaire.Name + "|"
			if verifiedQuestionnaires.IndexOf(verifyQuestionnaire) < 0  then
				verifiedQuestionnaires = verifiedQuestionnaires + verifyQuestionnaire
				' Get the documents needed to be attached from the questionnaire version.
				documentsToBeAttached = qV.documents
	            
				'The following for loop checks the availability of the required documents
           		For Each qD As FormsManagement.QuestionDocument In documentsToBeAttached
           			If (qD.Type <> Nothing) Then
               			If (qD.IsRequired) Then
							
       						dim supposedPDCountForQDType as integer = 0
       						dim actualPDCountForQDType as integer = 0

							'Get the type of the question. If the question's type is MultiInput or DropDownMultiSelect, then for each entry, need a enforce a document
							dim isMultiInputOrMultiSelect as boolean = false
							for each item as FormsManagement.QuestionnaireItem in qV.Items
								if (item.Name = qD.ItemName) then
									if (item.Type = FormsManagement.QuestionnaireItem.MultiSelectItemType or item.Type = FormsManagement.QuestionnaireItem.DropDownMultiSelectItemType) then
										isMultiInputOrMultiSelect = true
									end if
									exit for
								end if
							next
					
							'if (questionnaireAnswer.VersionAllowsMultiple) then
								dim similarQAs as ArrayList
								similarQAs = intrinsicProtocolVersion.GetAllQVQAs(questionnaireAnswer.QuestionnaireVersion.Id)
								
								if (not isMultiInputOrMultiSelect) then
									for each qA as FormsManagement.QuestionnaireAnswer in similarQAs
										For each answer as FormsManagement.Answer in qA.GetAnswers(qD.ItemName)
											if (answer.value = qD.ItemValue) then
												
												supposedPDCountForQDType = supposedPDCountForQDType + 1
												exit for
											end if
										Next
									next
								else 
									for each qA as FormsManagement.QuestionnaireAnswer in similarQAs
										supposedPDCountForQDType = supposedPDCountForQDType + questionnaireAnswer.GetAnswers(qD.ItemName).Count
									next
									
								end if
								
								'Get the attached documents from the protocol document.
								For Each pD As Humans.ProtocolDocument In intrinsicProtocolProcess.ProtocolDocuments
									'If the user has opted to send the hard copy of the document,No Log Item should be logged.
									If ((qD.Type = pD.Type) and (pD.IsHardCopy or pD.DocumentId >0)) Then
										actualPDCountForQDType = actualPDCountForQDType + 1
									End if  
								Next 
								
								If supposedPDCountForQDType > actualPDCountForQDType Then
									Dim logItem As New Humans.LogItem(intrinsicCachePolicy, intrinsicProtocolProcess.Id, -1, -1, "Attachments", "Attachments", qD.ItemName, qD.ItemValue, qD.ValidationMessage, false)
									SaveLogItem(logItem)
									attachmentsLogItemAdded = true
								End If
							'end if 'version allows multiple
						End If
					end if
           		Next ' 'end for loop that checks the availability of the required documents
           	end if
		next 'QUESTIONNAIRE ANSWER	
	
	
		'verify if all the ProtocolDocument records are either marked as hardcopy or there is an attachment tied to it
		If not attachmentsLogItemAdded then
			For Each pD As Humans.ProtocolDocument In intrinsicProtocolProcess.ProtocolDocuments
				If not (pD.IsHardCopy or pD.DocumentId >0) Then
					LogMissingItem(AttachmentsPageRedirection, AttachmentsPageRedirection, _
							"Attachments", string.empty, string.empty, string.empty, "Attachment missing for " + pD.Name)
				End if  
			Next
		End If
		
		
		' Check that they've answered the Primary Sponsor question only once. 
		if (sponsorChange and primarySponsorCount <> 1) then
			if primarySponsorCount = 0 and not sponsorTypeNone then
				LogMissingItem(-2, -2, "Sponsor Funding", string.empty, string.empty, string.empty, "The protocol must have a Primary Sponsor. You must indicate this by answering yes to the Primary sponsor question.")			
			else if primarySponsorCount > 1 then
				LogMissingItem(-2, -2, "Sponsor Funding", string.empty, string.empty, string.empty, "You have answered yes to the Primary Sponsor question for more than one sponsor. Only one can be marked as the Primary sponsor.")			
			end if			
		end if

		
    End Sub
    
    private function LogMissingItem(byval questionnaireVersionId as integer, byval questionnaireAnswerId as integer, byval logType as string, byval category as string, byval questionName as string, byval answer as string, byval description as string)
		Dim logItem As New Humans.LogItem(intrinsicCachePolicy)
		logItem.QuestionnaireVersionId = questionnaireVersionId
		logItem.QuestionnaireAnswerId = questionnaireAnswerId
		logItem.Type = logType
		logItem.QuestionName = questionName
		logItem.Category = category
		logItem.Answer = answer
		logItem.Description = description
		logItem.Completed =False
		SaveLogItem(logItem)
	end function

	'Save LogItem
	Sub SaveLogItem(ByVal logItem As Humans.LogItem)
		intrinsicProtocolProcess.SaveLogItem(logItem)
    End Sub
									
end module